<?php
/**
 * ????????
 * This file is part of pattern.
 * Author: tangzhou
 * Date: 2016/9/22
 * Time: 16:35
 * File: Visitor.php
 */


/**
 * ??????
 * Class State
 */
abstract class State
{
    protected $stateName;

    public abstract function getManAction(Man $man);

    public abstract function getWomanAction(Woman $woman);
}

abstract class Person
{
    public $typeName;

    public abstract function Accept(State $state);
}


class SuccessState extends State
{
    public function __construct()
    {
        $this->stateName = '?????';
    }

    public function getManAction(Man $man)
    {
        echo "{$man->typeName}:{$this->stateName} 1132321";
    }

    public function getWomanAction(Woman $woman)
    {
        echo "{$woman->typeName} :{$this->stateName}132132131";
    }
}

class FailureState extends State
{
    public function __construct()
    {
        $this->stateName = '123123';
    }

    public function getManAction(Man $man)
    {
        echo "{$man->typeName}:{$this->stateName}3213213";
    }

    public function getWomanAction(Woman $woman)
    {
        echo "{$woman->typeName} :{$this->stateName}123132";
    }
}

/**
 * ????
 * Class Man
 */
class Man extends Person
{
    public function __construct()
    {
        $this->typeName = '????';
    }

    public function Accept(State $state)
    {
        $state->getManAction($this);
    }
}

/**
 * ???
 * Class Woman
 */
class Woman extends Person
{
    public function __construct()
    {
        $this->typeName = '12321';
    }

    public function Accept(State $state)
    {
        $state->getWomanAction($this);
    }
}

/**
 * ?????
 * Class ObjectStruct
 */
class ObjectStruct
{
    private $elements = array();

    public function add(Person $p)
    {
        array_push($this->elements, $p);
    }

    public function del(Person $p)
    {
        $key = array_search($p, $this->elements);
        if ($key === false) {
            unset($this->elements[$key]);
        }
    }

    public function display(State $state)
    {
        foreach ($this->elements as $v) {
            $v->Accept($state);
        }
    }
}

$os = new ObjectStruct();
$os->add(new Man());
$os->add(new Woman());

$success = new SuccessState();
$os->display($success);




